로딩 중이에요... 🐣
[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
19 비동기화의 이해와 테스트 | ✅ 저자: 이유정(박사)
비동기 프로그램이란?
비동기 프로그래밍은 어떤 작업이 오래 걸려도 그 작업이 끝날 때까지 기다리지 않고, 다른 작업들을 그 사이에 동시에 처리할 수 있게 해주는 방식이에요.
즉, “누군가를 기다리는 동안 딴 일을 할 수 있다”는 거예요.
예: 세탁기 돌려놓고, 설거지하고, TV도 보고!
비동기 프로그램의 대표적인 특징:
1.
응답성이 좋다
사용자가 무언가 요청했을 때, 백엔드 서버가 느리게 반응하거나 멈추지 않아요.
시간이 오래 걸리는 작업이 있어도 다른 요청을 계속 처리할 수 있어요.
2.
확장하기 쉽다
작업을 잘게 나눠서 따로따로 실행하니까, 나중에 작업을 더 추가해도
시스템이 무너지지 않고 유연하게 확장할 수 있어요.
3.
자원을 아낀다
하나의 서버가 처리할 수 있는 일을 더 많이 하게 되니,
CPU나 메모리를 덜 쓰고도 더 많은 요청을 처리할 수 있어요.
4.
동시에 여러 작업 처리 가능
한꺼번에 여러 작업을 실행해서 전체 처리 속도를 줄이고,
사용자 입장에서는 빠르게 응답 받는 느낌이 들어요.
비동기 방식이 특히 효과적인 작업들: 첫째, 파일 읽기/쓰기
- 예: CSV 파일이나 로그 파일을 읽거나 저장할 때
- 오래 걸리는 동안 다른 요청을 동시에 처리할 수 있어요.
둘째, 데이터베이스 작업
- DB에 저장하거나 조회하는 작업은 속도가 느릴 수 있으므로, 기다리는 동안 다른 작업을 처리할 수 있어요.
셋째, 예약된 작업(스케줄 작업)
- 주기적으로 돌아가는 작업(ex. 하루 한 번 이메일 보내기)도
메인 서버 흐름을 방해하지 않고 따로 처리할 수 있어요.
넷째, 원격 서버 작업
- 외부 API에 요청을 보내고 응답을 기다리는 경우,
다른 작업을 멈추지 않고 그 사이에 계속 진행할 수 있어요.
실험코드(비동기 vs 동기 비교)
# async_demo.py
from fastapi import FastAPI
import time
import asyncio
app = FastAPI()
# 동기식 작업 함수
def sync_job(number: int):
for i in range(1, number + 1):
print(f"Job: #{number} | Task #{i}")
time.sleep(1) # blocking (다음 코드 실행 멈춤)
print(f"> Job: #{number} Done!")
# 비동기식 작업 함수
async def async_job(number: int):
for i in range(1, number + 1):
print(f"Job: #{number} | Task #{i}")
await asyncio.sleep(1) # non-blocking (다른 작업과 병렬 실행 가능)
print(f"> Job: #{number} Done!")
# 테스트 라우터
@app.get("/")
async def root():
print("=" * 80)
start = time.time()
# 동기 작업 순차 실행 (총 약 6초 소요)
sync_job(3)
sync_job(2)
sync_job(1)
end = time.time()
print(f">>> Processing time of sync_job: {end - start:.4f}초")
print("=" * 80)
print("=" * 80)
start = time.time()
# 비동기 작업 병렬 실행 (총 약 3초 소요)
await asyncio.wait([
asyncio.create_task(async_job(3)),
asyncio.create_task(async_job(2)),
asyncio.create_task(async_job(1)),
])
end = time.time()
print(f">>> Processing time of async_job: {end - start:.4f}초")
동기식코드=========================================================
Job: #3 | Task #1
Job: #3 | Task #2
Job: #3 | Task #3
> Job: #3 Done!
Job: #2 | Task #1
Job: #2 | Task #2
> Job: #2 Done!
Job: #1 | Task #1
> Job: #1 Done!
>>> Processing time of sync_job: 6.0008초
비동기식코드========================================================
Job: #3 | Task #1
Job: #2 | Task #1
Job: #1 | Task #1
Job: #3 | Task #2
Job: #2 | Task #2
> Job: #1 Done!
Job: #3 | Task #3
> Job: #2 Done!
> Job: #3 Done!
>>> Processing time of async_job: 3.0000초
==================================================================
INFO: 127.0.0.1:48880 - "GET / HTTP/1.1" 200 OK